package cn.iocoder.yudao.module.wecom.service.providerconfig;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
import cn.iocoder.yudao.module.wecom.dal.dataobject.providerconfig.WeComProviderConfigDO;
import cn.iocoder.yudao.module.wecom.dal.mysql.providerconfig.WeComProviderConfigMapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class WeComProviderConfigServiceImpl implements WeComProviderConfigService {

    @Resource
    private WeComProviderConfigMapper weComProviderConfigMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 获取
     */
    private static final String GET_SUITE_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/service/get_suite_token";

    @Override
    public void saveSuiteTicketConfig(Map<String, Object> params) {
        String suiteTicket = params.get("SuiteTicket").toString();
        String suiteId = params.get("SuiteId").toString();
        WeComProviderConfigDO apiConfig = getProviderConfig();
        if (ObjectUtil.equal(suiteId, apiConfig.getSuiteId())) {
            log.debug("更新服务商APP - SuiteTicket --- ");
            weComProviderConfigMapper.update(new LambdaUpdateWrapper<WeComProviderConfigDO>().set(WeComProviderConfigDO::getSuiteTicket, suiteTicket));
            apiConfig.setSuiteTicket(suiteTicket);
            refreshAppSuiteAccessToken(apiConfig);
        } else if (ObjectUtil.equal(suiteId, apiConfig.getLoginSuiteId())) {
            log.debug("更新登录授权APP - SuiteTicket --- ");
            apiConfig.setLoginTicket(suiteTicket);
            refreshLoginSuiteAccessToken(apiConfig);
            weComProviderConfigMapper.update(new LambdaUpdateWrapper<WeComProviderConfigDO>().set(WeComProviderConfigDO::getLoginTicket, suiteTicket));
        } else if (ObjectUtil.equal(suiteId, apiConfig.getContactSuiteId())) {
            log.debug("更新通讯录APP - SuiteTicket --- ");
            apiConfig.setContactTicket(suiteTicket);
            refreshContactSuiteAccessToken(apiConfig);
            weComProviderConfigMapper.update(new LambdaUpdateWrapper<WeComProviderConfigDO>().set(WeComProviderConfigDO::getContactTicket, suiteTicket));
        } else if (ObjectUtil.equal(suiteId, apiConfig.getConversationSuiteId())) {
            log.debug("更新会话存档APP - SuiteTicket --- ");
            apiConfig.setConversationTicket(suiteTicket);
            refreshConversationSuiteAccessToken(apiConfig);
            weComProviderConfigMapper.update(new LambdaUpdateWrapper<WeComProviderConfigDO>().set(WeComProviderConfigDO::getConversationTicket, suiteTicket));
        } else if (ObjectUtil.equal(suiteId, apiConfig.getAcqSuiteId())) {
            log.debug("更新获客助手APP - SuiteTicket --- ");
            apiConfig.setAcqTicket(suiteTicket);
            refreshAcqSuiteAccessToken(apiConfig);
            weComProviderConfigMapper.update(new LambdaUpdateWrapper<WeComProviderConfigDO>()
                    .set(WeComProviderConfigDO::getAcqTicket, suiteTicket));
        }
    }

    @Override
    public WeComProviderConfigDO getProviderConfig() {
        WeComProviderConfigDO providerConfig = weComProviderConfigMapper.selectOne(new LambdaQueryWrapperX<>());
        return providerConfig;
    }

    public void refreshAppSuiteAccessToken(WeComProviderConfigDO providerConfig) {

        if(ObjUtil.isNotEmpty(stringRedisTemplate.opsForValue().get("wecom_app_suite_access_token"))){
            return;
        }
        if (StrUtil.isAllNotEmpty(providerConfig.getSuiteId(), providerConfig.getSuiteSecret(), providerConfig.getSuiteTicket())) {
            Map<String, Object> postData = new HashMap<>();
            postData.put("suite_id", providerConfig.getSuiteId());
            postData.put("suite_secret", providerConfig.getSuiteSecret());
            postData.put("suite_ticket", providerConfig.getSuiteTicket());
            String resp = HttpUtil.createPost(GET_SUITE_TOKEN_URL)
                    .body(JSONUtil.toJsonStr(postData))
                    .execute()
                    .body();
            JSONObject result = JSONUtil.parseObj(resp);
            log.debug("SuiteAccessToken 请求: >>>>> {}", postData);
            log.debug("SuiteAccessToken 响应: >>>>> {}", result);
            String suiteAccessToken = result.getStr("suite_access_token");
            if (StrUtil.isNotEmpty(suiteAccessToken)) {
                Integer expireIn = result.getInt("expires_in");
                providerConfig.setSuiteAccessToken(suiteAccessToken);
                providerConfig.setSuiteAccessTokenExpireIn(expireIn);
                weComProviderConfigMapper.update(new LambdaUpdateWrapper<WeComProviderConfigDO>()
                        .eq(WeComProviderConfigDO::getId, providerConfig.getId())
                        .set(WeComProviderConfigDO::getSuiteAccessToken, suiteAccessToken)
                        .set(WeComProviderConfigDO::getSuiteAccessTokenExpireIn, expireIn)
                        .set(WeComProviderConfigDO::getUpdateTime, LocalDateTime.now())
                );
                stringRedisTemplate.opsForValue().set("wecom_app_suite_access_token", JSONUtil.toJsonStr(providerConfig), providerConfig.getSuiteAccessTokenExpireIn() - 1800, TimeUnit.SECONDS);
            }

            log.debug("SuiteAccessToken更新完毕: >>>>> {}", suiteAccessToken);
        }
    }

    public void refreshLoginSuiteAccessToken(WeComProviderConfigDO providerConfig) {
// 登录授权的suiteAccessToken
        if (StrUtil.isAllNotEmpty(providerConfig.getLoginSuiteId(), providerConfig.getLoginSecret(), providerConfig.getLoginTicket())) {
            Map<String, Object> postData = new HashMap<>();
            postData.put("suite_id", providerConfig.getLoginSuiteId());
            postData.put("suite_secret", providerConfig.getLoginSecret());
            postData.put("suite_ticket", providerConfig.getLoginTicket());
            String resp = HttpUtil.createPost(GET_SUITE_TOKEN_URL)
                    .body(JSONUtil.toJsonStr(postData))
                    .execute()
                    .body();
            JSONObject result = JSONUtil.parseObj(resp);
//            log.info("登录授权accessToken 请求: >>>>> {}", postData);
//            log.info("登录授权accessToken 响应: >>>>> {}", result);
            String suiteAccessToken = result.getStr("suite_access_token");
            if (StrUtil.isNotEmpty(suiteAccessToken)) {
                weComProviderConfigMapper.update(new LambdaUpdateWrapper<WeComProviderConfigDO>()
                        .set(WeComProviderConfigDO::getLoginSuiteAccessToken, suiteAccessToken)
                );
            }

            log.debug("登录授权accessToken: >>>>> {}", suiteAccessToken);
        }
    }

    public void refreshContactSuiteAccessToken(WeComProviderConfigDO providerConfig) {
        if (StrUtil.isAllNotEmpty(providerConfig.getContactSuiteId(), providerConfig.getContactSecret(), providerConfig.getContactTicket())) {
            Map<String, Object> postData = new HashMap<>();
            postData.put("suite_id", providerConfig.getContactSuiteId());
            postData.put("suite_secret", providerConfig.getContactSecret());
            postData.put("suite_ticket", providerConfig.getContactTicket());
            String resp = HttpUtil.createPost(GET_SUITE_TOKEN_URL)
                    .body(JSONUtil.toJsonStr(postData))
                    .execute()
                    .body();
            JSONObject result = JSONUtil.parseObj(resp);
//            log.info("通讯录AccessToken 请求: >>>>> {}", postData);
//            log.info("通讯录AccessToken 响应: >>>>> {}", result);
            String suiteAccessToken = result.getStr("suite_access_token");
            if (StrUtil.isNotEmpty(suiteAccessToken)) {
                weComProviderConfigMapper.update(new LambdaUpdateWrapper<WeComProviderConfigDO>()
                        .set(WeComProviderConfigDO::getContactSuiteAccessToken, suiteAccessToken)
                );
            }
            log.debug("通讯录AccessToken: >>>>> {}", suiteAccessToken);
        }
    }

    /**
     * 更新会话存档accessToken
     *
     * @param providerConfig
     * @author PetePower
     * @since 2024-07-29
     */
    public void refreshConversationSuiteAccessToken(WeComProviderConfigDO providerConfig) {
        if (StrUtil.isAllNotEmpty(providerConfig.getConversationSuiteId(), providerConfig.getConversationSecret(), providerConfig.getConversationTicket())) {
            Map<String, Object> postData = new HashMap<>();
            postData.put("suite_id", providerConfig.getConversationSuiteId());
            postData.put("suite_secret", providerConfig.getConversationSecret());
            postData.put("suite_ticket", providerConfig.getConversationTicket());
            String resp = HttpUtil.createPost(GET_SUITE_TOKEN_URL)
                    .body(JSONUtil.toJsonStr(postData))
                    .execute()
                    .body();
            JSONObject result = JSONUtil.parseObj(resp);
//            log.info("会话存档AccessToken 请求: >>>>> {}", postData);
//            log.info("会话存档AccessToken 响应: >>>>> {}", result);
            String suiteAccessToken = result.getStr("suite_access_token");
            if (StrUtil.isNotEmpty(suiteAccessToken)) {
                weComProviderConfigMapper.update(new LambdaUpdateWrapper<WeComProviderConfigDO>()
                        .set(WeComProviderConfigDO::getConversationSuiteAccessToken, suiteAccessToken)
                );
            }
            log.debug("会话存档AccessToken: >>>>> {}", suiteAccessToken);
        }
    }

    /**
     * 更新会话存档accessToken
     *
     * @param providerConfig
     * @author PetePower
     * @since 2024-07-29
     */
    public void refreshAcqSuiteAccessToken(WeComProviderConfigDO providerConfig) {
        if (StrUtil.isAllNotEmpty(providerConfig.getAcqSuiteId(), providerConfig.getAcqSecret(), providerConfig.getAcqTicket())) {
            Map<String, Object> postData = new HashMap<>();
            postData.put("suite_id", providerConfig.getAcqSuiteId());
            postData.put("suite_secret", providerConfig.getAcqSecret());
            postData.put("suite_ticket", providerConfig.getAcqTicket());
            String resp = HttpUtil.createPost(GET_SUITE_TOKEN_URL)
                    .body(JSONUtil.toJsonStr(postData))
                    .execute()
                    .body();
            JSONObject result = JSONUtil.parseObj(resp);
//            log.info("获客助手AccessToken 请求: >>>>> {}", postData);
//            log.info("获客助手AccessToken 响应: >>>>> {}", result);
            String suiteAccessToken = result.getStr("suite_access_token");
            if (StrUtil.isNotEmpty(suiteAccessToken)) {
                weComProviderConfigMapper.update(new LambdaUpdateWrapper<WeComProviderConfigDO>()
                        .set(WeComProviderConfigDO::getAcqSuiteAccessToken, suiteAccessToken)
                );
            }
            log.debug("获客助手AccessToken: >>>>> {}", suiteAccessToken);
        }
    }
}
